package cn.itcast.bos.web.action.base;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import cn.itcast.bos.domain.base.Area;
import cn.itcast.bos.domain.base.Courier;
import cn.itcast.bos.service.base.AreaService;
import cn.itcast.bos.utils.PinYin4jUtils;
import cn.itcast.bos.web.action.common.BaseAction;


@Controller
@Scope("prototype")
@Namespace("/")
@ParentPackage("json-default")
public class AreaAction extends BaseAction<Area>{
  
	
	
	
	//注入service层
	@Autowired
	private AreaService areaService;
	
	 //属性驱动接收上传文件
	private File file2;
	private String  file2FileName;

	public void setFile2(File file2) {
		this.file2 = file2;
	}
	
	public void setFile2FileName(String file2FileName) {
		this.file2FileName = file2FileName;
	}




	/**
	 * 批量导入功能
	 *  
	 * 
	 */
	@Action(value="area_batchImport",results={@Result(name="success",type="redirect",location="./pages/base/area.html")})
	public String batchImport() throws Exception{
	
	List<Area> areas=new ArrayList<Area>();	
	
	//判断文件.xls和.xlsx哪种格式	
	
	//  String[] split = file2.getName().split("\\.");因为struts2拦截器的设置，导致这里不能直接获取名字
	
	
	if(file2FileName.endsWith(".xls")){
		
	//创建解析.xls格式文件的对象HSSF	
	HSSFWorkbook hwb=new  HSSFWorkbook(new FileInputStream(file2));	
		
	//读取一个工作簿
	HSSFSheet sheet = hwb.getSheetAt(0);	
	
	//读取工作簿的每一行
	for(Row row:sheet){
	//跳过第一行表头的内容
	if(row.getRowNum()==0){
		continue;
	}
	
	//跳过空行，如果表的要求是不准有空行和空格，那么只有是读取完毕，这样可以用break结束，提高代码的执行效率
	if(row.getCell(0)==null || StringUtils.isBlank(row.getCell(0).getStringCellValue())){
	//此时改行为空行，跳过	
		continue;	
	}
	
	//创建一个对象，封装表格的数据
	Area area=new Area();
	//获取该行每一列的值
	area.setId(row.getCell(0).getStringCellValue());
	area.setProvince(row.getCell(1).getStringCellValue());
	area.setCity(row.getCell(2).getStringCellValue());
	area.setDistrict(row.getCell(3).getStringCellValue());
	area.setPostcode(row.getCell(4).getStringCellValue());
	
	//使用pinyin4j将数据表中的城市编码和简码补全
	String district = area.getDistrict();//获取区名
	String city = area.getCity();//获取城市名
    String province = area.getProvince();//获取省名
	//将名字中最后的区，市，省去掉
    district=district.substring(0, district.length()-1);
    city=city.substring(0, city.length()-1);
    province=province.substring(0, province.length()-1);
    
    //简码是由各区名字的首字母大写组成HBWHJX（湖北武汉江夏）
    //调用自己写的工具类
    String[] headArray = PinYin4jUtils.getHeadByString(province+city+district);
    //遍历将数组进行拼接
    String shortcode="";
    for(String headStr :headArray){
    	shortcode+=headStr;	
    }
    //将简码赋值到area
    area.setShortcode(shortcode);
    
    //城市编码
    String citycode = PinYin4jUtils.hanziToPinyin(city,"");
    
    area.setCitycode(citycode);
	//将对象封装到集合
	areas.add(area);
	
	}
	
	}
	if(file2FileName.endsWith(".xlsx")){
	//创建解析.xlsx文件的对象	
	XSSFWorkbook xwb=new XSSFWorkbook(new FileInputStream(file2));
		
	//读取工作簿
	XSSFSheet sheet = xwb.getSheetAt(0);
	
	//读取工作簿的每一行数据，每行数据都是一个area对象
	for(Row row:sheet){
		
	
	//跳过第一行表头的内容
	if(row.getRowNum()==0){
		continue;
	}
	
	//跳过空行，如果表的要求是不准有空行和空格，那么只有是读取完毕，这样可以用break结束，提高代码的执行效率
	if(row.getCell(0)==null || StringUtils.isBlank(row.getCell(0).getStringCellValue())){
	//此时改行为空行，跳过	
		continue;
		
	}
	
	//创建一个对象，封装表格的数据
	Area area=new Area();
	area.setId(row.getCell(0).getStringCellValue());
	area.setProvince(row.getCell(1).getStringCellValue());
	area.setCity(row.getCell(2).getStringCellValue());
	area.setDistrict(row.getCell(3).getStringCellValue());
	area.setPostcode(row.getCell(4).getStringCellValue());
	
	
	//使用pinyin4j将数据表中的城市编码和简码补全
		String district = area.getDistrict();//获取区名
		String city = area.getCity();//获取城市名
	    String province = area.getProvince();//获取省名
		//将名字中最后的区，市，省去掉
	    district=district.substring(0, district.length()-1);
	    city=city.substring(0, city.length()-1);
	    province=province.substring(0, province.length()-1);
	    
	    //简码是由各区名字的首字母大写组成HBWHJX（湖北武汉江夏）
	    //调用自己写的工具类
	    String[] headArray = PinYin4jUtils.getHeadByString(province+city+district);
	    //遍历将数组进行拼接
	  //  String shortcode="";
	    StringBuffer sb=new StringBuffer();
	    for(String headStr :headArray){
	    	sb.append(headStr);
	    }
	    //将简码赋值到area
	    String shortcode = sb.toString();
	    area.setShortcode(shortcode);
	    
	    //城市编码
	    String citycode = PinYin4jUtils.hanziToPinyin(city,"");
	    
	    area.setCitycode(citycode);
	  
	   //将对象封装到集合
	   areas.add(area);
	}
	}
	
	//将上传的数据传到业务层
	areaService.saveBatch(areas);
	
	
		return SUCCESS;
	}

	
	/**
	 * 分页查询
	 */


	/*// 属性驱动，获取请求提交的参数
	private int page;// 当前页数
	private int rows;// 每页展示的记录条数

	// 提供setter方法

	public void setPage(int page) {
		this.page = page;
	}

	public void setRows(int rows) {
		this.rows = rows;
	}*/

	/**
	 * 页面加载完成后将数据展现在页面的分页操作
	 */

	@Action(value = "area_pageQuery", results = { @Result(name = "success", type = "json") })
	public String pageQuery() {

		// 将参数封装到pageable中
		Pageable pageable = new PageRequest(page-1, rows);

		
		 //根据查询条件构造Specification条件查询对象，类似Hiberbnate的QBC查询
		//这里用到了匿名内部类
		Specification<Area>	specification=new Specification<Area>() {

			/**
			 * 下面获取构造查询条件的方法，如果返回的值为null ,那么代表无条件查询,当页面刚刷新的时候，条件查询没有携带参数，做的是无条件的分页查询
			 * 
			 * 第一个参数root（实体类）,获取条件表达式里面的如：name=?,age=?
			 * 第二个参数query（简单查询）,构造简单的查询条件返回，提供where方法
			 * 第三个参数cb（复杂查询）,构造的Predicate对象，条件对象，构造复杂查询效果
			 */
			
			@Override
			public Predicate toPredicate(Root<Area> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
		    //首先创建一个list结合，将获取的条件查询的结果装入，然后再转换成数组，传递到底层
			List<Predicate>	list=new ArrayList<Predicate>();
			//判断请求传递过来的参数进行非空校验province,city,district,全部用模糊查询
		
			if(StringUtils.isNotBlank(model.getProvince())){
				//如果省份不为空，就将它的值赋给province
				
				Predicate p1 = cb.like(root.get("province").as(String.class), "%"+model.getProvince()+"%");
				
				list.add(p1);
			}
				
			if(StringUtils.isNotBlank(model.getCity())){
				//如果查询条件里面城市 like %?%
				
				Predicate p2 = cb.like(root.get("city").as(String.class), "%"+model.getCity()+"%");
				
				list.add(p2);
			}
			
			
			if(StringUtils.isNotBlank(model.getDistrict())){
				//如果查询条件里面城市 like %?%
				
				Predicate p3 = cb.like(root.get("district").as(String.class), "%"+model.getDistrict()+"%");
				
				list.add(p3);
			}
			
		  
			//将集合转换成数组new Predicate[list.size()],这里可以传递数组的元素的个数页可以传0，方法底层会根据给到的集合对象，创建相应长度的数组
			Predicate[] array = list.toArray(new Predicate[list.size()]);
			
				return cb.and(array);//and里面传递可变参数
			}
		};
		
		// 调用业务层处理数据
		Page<Area> page = areaService.findPageData(specification,pageable);
    
	/*	//将数据封装到map里面
		Map<String, Object> map=new HashMap<String, Object>();
		
		map.put("total", page.getTotalElements());//所有的记录数
		map.put("rows", page.getContent());//当前页面展示的所有数据
		
		//将结果存到值栈，置顶
		ServletActionContext.getContext().getValueStack().push(map);
		*/
		
	pushPageDataToValueStack(page);
		
		return SUCCESS;
	}

	

	
	
	
}
